package tech.shupi.babytapmobile.service

import android.app.*
import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import tech.shupi.babytapmobile.MainActivity
import mobile.HTTPSServer
import java.io.File
import java.util.concurrent.atomic.AtomicBoolean


/**
 * Golang API 前台服务
 * 通过 gomobile 管理 Golang HTTPS 服务器的生命周期
 */
class GolangApiService : Service() {

    companion object {
        private const val TAG = "GolangApiService"
        private const val NOTIFICATION_ID = 1001
        private const val CHANNEL_ID = "baby_tap_golang_api_channel"
        private const val CHANNEL_NAME = "Baby Tap Golang API"
        private const val DEFAULT_PORT = 8553
        private const val PORT_RANGE_START = 8553
        private const val PORT_RANGE_END = 8600
        private const val STARTUP_TIMEOUT_MS = 10000L // 10秒启动超时
        private const val MAX_RETRY_COUNT = 3 // 最大重试次数

    }

    private val binder = LocalBinder()
    private var golangServer: HTTPSServer? = null
    private val isRunning = AtomicBoolean(false)
    private var serverPort = DEFAULT_PORT
    private var actualPort = DEFAULT_PORT
    private var startupStartTime = 0L
    private var isForegroundStarted = false


    
    // 优化：使用 ExecutorService 管理线程
    private val serverExecutor = java.util.concurrent.Executors.newSingleThreadExecutor()
    private val serverStartFuture = java.util.concurrent.atomic.AtomicReference<java.util.concurrent.Future<*>?>()

    inner class LocalBinder : Binder() {
        fun getService(): GolangApiService = this@GolangApiService
    }

    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "GolangApiService onCreate")
        createNotificationChannel()
        requestNotificationPermission()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "GolangApiService onStartCommand")

        when (intent?.action) {
            "START_API" -> startGolangServer()
            "STOP_API" -> stopGolangServer()
        }

        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder {
        return binder
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "GolangApiService onDestroy")
        stopGolangServer()
        
        // 优化：清理线程池资源
        try {
            serverStartFuture.get()?.cancel(true)
            serverExecutor.shutdown()
            if (!serverExecutor.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS)) {
                serverExecutor.shutdownNow()
            }
            Log.d(TAG, "✅ 线程池资源清理完成")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 清理线程池资源失败", e)
        }
    }

    /**
     * 启动 Golang API 服务器
     */
    fun startGolangServer() {
        if (isRunning.get()) {
            Log.w(TAG, "Golang API 服务器已经在运行")
            return
        }

        startupStartTime = System.currentTimeMillis()

        // 立即启动前台服务，避免超时
        if (!isForegroundStarted) {
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                startForeground(
                    NOTIFICATION_ID,
                    createNotification(),
                    android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
                )
            } else {
                startForeground(NOTIFICATION_ID, createNotification())
            }
            isForegroundStarted = true
            Log.i(TAG, "✅ 前台服务已启动")
        }

        // 在后台线程中启动服务器
        Thread {
            try {
                Log.i(TAG, "🚀 开始启动 Golang API 服务器...")

                // 获取外部存储数据目录
                val dataDir = File(getExternalFilesDir(null), "golang_data").absolutePath
                Log.d(TAG, "外部存储数据目录: $dataDir")

                // 检查目录是否存在
                val dataDirFile = File(dataDir)
                Log.d(TAG, "数据目录是否存在: ${dataDirFile.exists()}")
                if (dataDirFile.exists()) {
                    Log.d(TAG, "数据目录内容: ${dataDirFile.listFiles()?.joinToString { it.name }}")
                }

                // 尝试启动服务器（带重试机制）
                var retryCount = 0
                var success = false

                while (retryCount < MAX_RETRY_COUNT && !success) {
                    try {
                        if (retryCount > 0) {
                            Log.w(TAG, "重试启动服务器 (第 ${retryCount + 1} 次)")
                            Thread.sleep(1000) // 等待1秒后重试
                        }

                        // 尝试使用动态端口创建服务器
                        try {
                            Log.d(TAG, "尝试使用动态端口创建 Golang 服务器...")
                            golangServer = HTTPSServer(dataDir)  // 使用只带数据目录的构造函数
                            actualPort = golangServer?.getPort()?.toInt() ?: DEFAULT_PORT
                            Log.i(TAG, "✅ 使用动态端口创建服务器成功，实际端口: $actualPort")
                        } catch (e: Exception) {
                            Log.w(TAG, "动态端口创建失败，尝试使用指定端口: $serverPort", e)

                            // 检查指定端口是否可用
                            if (golangServer?.checkPortAvailability(serverPort.toLong()) == true) {
                                golangServer =
                                    HTTPSServer(serverPort.toLong(), dataDir)  // 使用带端口和数据目录的构造函数
                                actualPort = serverPort
                                Log.i(TAG, "✅ 使用指定端口创建服务器成功: $actualPort")
                            } else {
                                throw Exception("端口 $serverPort 不可用，且动态端口创建失败")
                            }
                        }

                        // 优化：使用 ExecutorService 启动服务器
                        Log.d(TAG, "在后台线程中启动 Golang 服务器，端口: $actualPort...")
                        
                        val future = serverExecutor.submit {
                            try {
                                Log.d(TAG, "🚀 开始调用 golangServer.start()...")
                                golangServer?.start()
                                Log.d(TAG, "✅ Golang 服务器 start() 调用完成")
                                true // 返回成功标志
                            } catch (e: Exception) {
                                Log.e(TAG, "❌ golangServer.start() 调用失败", e)
                                false // 返回失败标志
                            }
                        }
                        serverStartFuture.set(future)
                        
                        // 等待服务器启动完成（带超时）
                        val startupTime = System.currentTimeMillis() - startupStartTime
                        Log.d(TAG, "服务器启动耗时: ${startupTime}ms")
                        
                        if (startupTime > STARTUP_TIMEOUT_MS) {
                            throw Exception("服务器启动超时 (${startupTime}ms > ${STARTUP_TIMEOUT_MS}ms)")
                        }

                        // 优化：等待服务器真正启动
                        try {
                            val serverStarted = future.get(5, java.util.concurrent.TimeUnit.SECONDS) as Boolean
                            if (!serverStarted) {
                                throw Exception("服务器启动失败")
                            }
                        } catch (e: java.util.concurrent.TimeoutException) {
                            Log.w(TAG, "服务器启动超时，但继续执行...")
                        } catch (e: Exception) {
                            Log.e(TAG, "服务器启动失败", e)
                            throw e
                        }

                        success = true
                        Log.i(
                            TAG,
                            "✅ Golang API 服务器启动成功，端口: $actualPort (耗时: ${startupTime}ms)"
                        )

                    } catch (e: Exception) {
                        retryCount++
                        Log.e(TAG, "启动失败 (第 $retryCount 次): ${e.message}", e)

                        // 清理失败的服务器实例
                        try {
                            golangServer?.stop()
                        } catch (stopError: Exception) {
                            Log.w(TAG, "清理失败服务器实例时出错", stopError)
                        }
                        golangServer = null

                        if (retryCount >= MAX_RETRY_COUNT) {
                            throw Exception("服务器启动失败，已重试 $MAX_RETRY_COUNT 次: ${e.message}")
                        }
                    }
                }

                if (success) {
                    Log.d(TAG, "🎯 服务器启动成功，开始后续处理...")
                    isRunning.set(true)
                    Log.d(TAG, "✅ isRunning 设置为 true")

                    // 更新通知内容
                    updateNotification()
                    Log.d(TAG, "✅ 通知已更新")

                    val totalTime = System.currentTimeMillis() - startupStartTime
                    Log.i(TAG, "🎉 Golang API 服务器完全启动成功！总耗时: ${totalTime}ms")
                    Log.d(TAG, "📡 UDP 发现服务已通过 Go 服务器启动")
                } else {
                    Log.w(TAG, "❌ 服务器启动失败，success = false")
                    // 启动失败，停止前台服务
                    if (isForegroundStarted) {
                        stopForeground(STOP_FOREGROUND_REMOVE)
                        isForegroundStarted = false
                    }
                }

            } catch (e: Exception) {
                Log.e(TAG, "❌ 启动 Golang API 服务器失败", e)
                isRunning.set(false)
                golangServer = null

                // 启动失败，停止前台服务
                if (isForegroundStarted) {
                    stopForeground(STOP_FOREGROUND_REMOVE)
                    isForegroundStarted = false
                }
            }
        }.start()
    }

    /**
     * 停止 Golang API 服务器
     */
    fun stopGolangServer() {
        if (!isRunning.get()) {
            Log.w(TAG, "Golang API 服务器未运行")
            return
        }

        try {
            Log.i(TAG, "停止 Golang API 服务器...")
            
            // 优化：取消正在进行的服务器启动任务
            serverStartFuture.get()?.cancel(true)
            
            golangServer?.stop()
            golangServer = null

            isRunning.set(false)

            // 停止前台服务
            if (isForegroundStarted) {
                stopForeground(STOP_FOREGROUND_REMOVE)
                isForegroundStarted = false
            }
            stopSelf()

            Log.i(TAG, "✅ Golang API 服务器停止成功")

        } catch (e: Exception) {
            Log.e(TAG, "❌ 停止 Golang API 服务器失败", e)
        }
    }

    /**
     * 检查服务器状态
     */
    fun isServerRunning(): Boolean {
        return isRunning.get() && golangServer?.isRunning() == true
    }

    /**
     * 获取服务器端口
     */
    fun getServerPort(): Int {
        return actualPort
    }

    /**
     * 获取配置的端口
     */
    fun getConfiguredPort(): Int {
        return serverPort
    }

    /**
     * 设置服务器端口
     */
    fun setServerPort(port: Int) {
        serverPort = port
        Log.d(TAG, "设置服务器端口: $port")
    }

    /**
     * 获取启动耗时
     */
    fun getStartupTime(): Long {
        return if (startupStartTime > 0) System.currentTimeMillis() - startupStartTime else 0
    }

    /**
     * 更新通知内容
     */
    private fun updateNotification() {
        if (isForegroundStarted) {
            val notification = createNotification()
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.notify(NOTIFICATION_ID, notification)
        }
    }

    /**
     * 请求通知权限
     */
    private fun requestNotificationPermission() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
            if (checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) != android.content.pm.PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "通知权限未授予，前台服务通知可能不可见")
            } else {
                Log.i(TAG, "✅ 通知权限已授予")
            }
        }
    }

    /**
     * 创建通知渠道
     */
    private fun createNotificationChannel() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT
            ).apply {
                description = "Baby Tap Golang API 服务通知"
                setShowBadge(true)
                enableLights(true)
                enableVibration(false)
            }

            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }

    /**
     * 创建通知
     */
    private fun createNotification(): Notification {
        val intent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }

        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val statusText = if (isRunning.get()) {
            "Golang API 服务器运行中 (端口 $actualPort)"
        } else {
            "正在启动 Golang API 服务器..."
        }

        return NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("宝宝点读卡 Golang API")
            .setContentText(statusText).setSmallIcon(android.R.drawable.ic_menu_manage)
            .setContentIntent(pendingIntent).setOngoing(true).setSilent(false)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setCategory(NotificationCompat.CATEGORY_SERVICE).build()
    }
}